package com.user.authentication;

import com.common.domain.pojo.Result;
import com.common.handler.RedisKeysHandler;
import com.common.properties.SecurityProperties;
import com.common.tool.JwtTool;
import com.common.tool.ResponseTool;
import com.user.domain.pojo.User;
import com.user.service.impl.UserServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler, ApplicationContextAware {
    private final SecurityProperties securityProperties;
    private final StringRedisTemplate stringRedisTemplate;
    private ApplicationContext applicationContext;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        UserServiceImpl userService = applicationContext.getBean(UserServiceImpl.class);
        UserDetails principal = (UserDetails) authentication.getPrincipal();
        User user = userService.querySelectByUsername(principal.getUsername());
        // 生成令牌
        String secretJwt = JwtTool.createSecretJwt(user.getUsername(), user.getId(), securityProperties.getAuthentication().getAccess_secretKey(), securityProperties.getAuthentication().getAccess_expireHours());
        String refreshJwt = JwtTool.createRefreshJwt(user.getUsername(), securityProperties.getAuthentication().getRefresh_secretKey(), securityProperties.getAuthentication().getRefresh_expireHours());
        LoginAuthentication loginAuthentication = new LoginAuthentication();
        loginAuthentication.setAccessToken(secretJwt);
        loginAuthentication.setRefreshToken(refreshJwt);
        loginAuthentication.setUserInfo(userService.UserToInfo(user));
        loginAuthentication.setRoleNames(userService.getUserRoleNameList(user.getId()));
        // 将认证信息存储到 redis 中
        stringRedisTemplate.delete(RedisKeysHandler.getTokenKey(user.getId()));    // 删除原始token信息
        stringRedisTemplate.opsForValue().set(RedisKeysHandler.getTokenKey(user.getId()),secretJwt,securityProperties.getAuthentication().getAccess_expireHours(), TimeUnit.HOURS);
        stringRedisTemplate.opsForValue().set(RedisKeysHandler.getTokenRefreshKey(user.getId()),refreshJwt,securityProperties.getAuthentication().getRefresh_expireHours(), TimeUnit.HOURS);
        ResponseTool.result(response,200, Result.success(loginAuthentication));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
